/*
 * Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
 *
 * Licensed under the Mulan PSL v2.
 * You can use this file according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of the License at
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
 * FOR MORE DETAILS.
 */

#pragma once

#include <cassert>
#include <functional>

#include "Utility/Algebra/Matrix.h"

#include "DataStructure/Common/Status.h"
#include "DataStructure/Input/Coordinate/ICoordinate.h"
#include "DataStructure/Input/Element/ElementTypes.h"

#include "DBManager/Common/DBManagerExport.h"
#include "DBManager/Common/DBManagerNamespace.h"

SG_DBMANAGER_NAMESPACE_OPEN

class DBServiceFactory;

class IDatabaseHub
{
  public:
    IDatabaseHub (/* args */);
    virtual ~IDatabaseHub ();

    // 清空信号槽
    virtual void ClearSignal ();
    ///

    /// @{
    /// @brief 对于Element的事件注册
    // 获取单元节点函数类型
    using FunFindElementNodes = std::function<std::vector<SG::DataStructure::Common::Id> (SG::DataStructure::Common::Id)>;

    std::map<SG::DataStructure::FEM::ElementTypes, FunFindElementNodes>& FindElementNodesFunMap ()
    {
        return m_getElementNodesByIdFunMap;
    }
    void ConnectFindElementNodes (SG::DataStructure::FEM::ElementTypes type, FunFindElementNodes funp)
    {
        m_getElementNodesByIdFunMap[type] = std::move (funp);
    }

    private:
    std::map<SG::DataStructure::FEM::ElementTypes, FunFindElementNodes> m_getElementNodesByIdFunMap;  ///< 获取某单元节点列表的函数指针Map

                                                                                                      /// @}
    /// @{
    /// @brief   : 对于Coordinate的事件注册
  public:
    using FunGetAllCoord = std::function<std::vector<std::shared_ptr<SG::DataStructure::FEM::ICoordinate>> ()>;

    /**
     * @brief   : 获取所有坐标系函数集合
     * @author  : wxc
     * @date    : 2024.11.16
     */
    std::vector<FunGetAllCoord>& GetAllCoordFunMap ()
    {
        return m_getAllCoordFunMap;
    }

    /**
     * @brief   : 连接获取所有坐标系函数
     * @param   : funp
     * @author  : wxc
     * @date    : 2024.11.16
     */
    void ConnectGetAllCoord (const FunGetAllCoord& funp)
    {
        m_getAllCoordFunMap.push_back (funp);
    }

  private:
    std::vector<FunGetAllCoord> m_getAllCoordFunMap;  ///< 获取所有坐标系函数

                                                      /// @}

    ///@{
    /// @brief   : 对于CopyData的事件注册
  public:
    using FunCopyData = std::function<SG::DataStructure::Common::Status (
        DBServiceFactory* const, DBServiceFactory* const, std::vector<SG::DataStructure::Common::Id>)>;
    std::map<std::size_t, FunCopyData>& CopyDataFunMap ()
    {
        return m_copyDataFunMap;
    }
    void ConnectCopyData (std::size_t type, FunCopyData funp)
    {
        m_copyDataFunMap[type] = std::move (funp);
    }

  private:
    std::map<std::size_t, FunCopyData> m_copyDataFunMap;  ///< 复制单元数据至其他数据库

                                                          /// @brief   : 对于CopyDataRes的事件注册
  public:
    using FunCopyDataRes = std::function<SG::DataStructure::Common::Status (std::vector<std::shared_ptr<DBServiceFactory>> srcs,
                                                                            std::shared_ptr<DBServiceFactory>              dest,
                                                                            std::vector<SG::DataStructure::Common::Id>     domainIds)>;

  private:
    static std::vector<FunCopyDataRes> s_copyDataResFunVec;  ///< 复制单元数据至其他数据库
  public:
    std::vector<FunCopyDataRes>& CopyDataResFunVec ()
    {
        return s_copyDataResFunVec;
    }
    static bool ConnectCopyDataRes (FunCopyDataRes funp)
    {
        s_copyDataResFunVec.push_back (std::move (funp));
        return true;
    }
};

SG_DBMANAGER_NAMESPACE_CLOSE
